package com.hikvision.artemis.sdk;

import com.hikvision.artemis.sdk.config.ArtemisConfig;
import com.hikvision.artemis.sdk.constant.Constants;
import com.hikvision.artemis.sdk.enums.Method;
import com.hikvision.artemis.sdk.util.MessageDigestUtil;
import io.enoa.toolkit.is.Is;
import org.apache.http.HttpResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;

public class ArtemisHttpUtil {
  private static final Logger logger = LoggerFactory.getLogger(ArtemisHttpUtil.class);
  private static final String SUCC_PRE = "2";
  private static final String REDIRECT_PRE = "3";

  public static String doGetArtemis(ArtemisConfig config, Map<String, String> path, Map<String, String> querys, String accept, String contentType, Map<String, String> header) {
    String httpSchema = (String) path.keySet().toArray()[0];
    if (Is.not().truthy(httpSchema)) {
      throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
    }
    String responseStr = null;
    try {
      Map<String, String> headers = new HashMap<String, String>();
      if (Is.truthy(accept)) {
        headers.put("Accept", accept);
      } else {
        headers.put("Accept", "*/*");
      }
      if (Is.truthy(contentType)) {
        headers.put("Content-Type", contentType);
      } else {
        headers.put("Content-Type", "application/text;charset=UTF-8");
      }
      if (header != null) {
        headers.putAll(header);
      }
      logger.info(path.get(httpSchema));
      Request request = new Request(Method.GET, httpSchema + config.host, path.get(httpSchema), config.appKey, config.appSecret, Constants.DEFAULT_TIMEOUT);
      request.setHeaders(headers);
      request.setQuerys(querys);
      Response response = Client.execute(request);
      responseStr = response.getBody();
    } catch (Exception e) {
      logger.error("the Artemis GET Request is failed[doGetArtemis]", e);
    }
    return responseStr;
  }

  public static String doGetArtemis(ArtemisConfig config, Map<String, String> path, Map<String, String> querys, String accept, String contentType) {
    String httpSchema = (String) path.keySet().toArray()[0];
    if (Is.not().truthy(httpSchema)) {
      throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
    }
    String responseStr = null;
    try {
      Map<String, String> headers = new HashMap<String, String>();
      if (Is.truthy(accept)) {
        headers.put("Accept", accept);
      } else {
        headers.put("Accept", "*/*");
      }
      if (Is.truthy(contentType)) {
        headers.put("Content-Type", contentType);
      } else {
        headers.put("Content-Type", "application/text;charset=UTF-8");
      }
      logger.info(path.get(httpSchema));
      Request request = new Request(Method.GET, httpSchema + config.host, path.get(httpSchema), config.appKey, config.appSecret, Constants.DEFAULT_TIMEOUT);
      request.setHeaders(headers);
      request.setQuerys(querys);
      Response response = Client.execute(request);
      responseStr = response.getBody();
    } catch (Exception e) {
      logger.error("the Artemis GET Request is failed[doGetArtemis]", e);
    }
    return responseStr;
  }

  public static HttpResponse doGetResponse(ArtemisConfig config, Map<String, String> path, Map<String, String> querys, String accept, String contentType, Map<String, String> header) {
    String httpSchema = (String) path.keySet().toArray()[0];
    if (Is.not().truthy(httpSchema)) {
      throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
    }
    HttpResponse httpResponse = null;
    try {
      Map<String, String> headers = new HashMap<String, String>();
      if (Is.truthy(accept)) {
        headers.put("Accept", accept);
      } else {
        headers.put("Accept", "*/*");
      }
      if (Is.truthy(contentType)) {
        headers.put("Content-Type", contentType);
      } else {
        headers.put("Content-Type", "application/text;charset=UTF-8");
      }
      if (header != null) {
        headers.putAll(header);
      }
      Request request = new Request(Method.GET_RESPONSE, httpSchema + config.host, path.get(httpSchema), config.appKey, config.appSecret, Constants.DEFAULT_TIMEOUT);
      request.setHeaders(headers);
      request.setQuerys(querys);
      Response response = Client.execute(request);
      httpResponse = response.getResponse();
    } catch (Exception e) {
      logger.error("the Artemis GET Request is failed[doGetArtemis]", e);
    }
    return httpResponse;
  }

  public static String doPostFormArtemis(ArtemisConfig config, Map<String, String> path, Map<String, String> paramMap, Map<String, String> querys, String accept, String contentType, Map<String, String> header) {
    String httpSchema = (String) path.keySet().toArray()[0];
    if (Is.not().truthy(httpSchema))
      throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
    String responseStr = null;
    try {
      Map<String, String> headers = new HashMap<String, String>();
      if (Is.truthy(accept)) {
        headers.put("Accept", accept);
      } else {
        headers.put("Accept", "*/*");
      }
      if (Is.truthy(contentType)) {
        headers.put("Content-Type", contentType);
      } else {
        headers.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
      }
      if (header != null) {
        headers.putAll(header);
      }
      Request request = new Request(Method.POST_FORM, httpSchema + config.host, path.get(httpSchema), config.appKey, config.appSecret, Constants.DEFAULT_TIMEOUT);
      request.setHeaders(headers);
      request.setQuerys(querys);
      request.setBodys(paramMap);
      Response response = Client.execute(request);
      responseStr = getResponseResult(response);
    } catch (Exception e) {
      logger.error("the Artemis PostForm Request is failed[doPostFormArtemis]", e);
    }
    return responseStr;
  }

  public static String doPostFormArtemis(ArtemisConfig config, Map<String, String> path, Map<String, String> paramMap, Map<String, String> querys, String accept, String contentType) {
    String httpSchema = (String) path.keySet().toArray()[0];
    if (Is.not().truthy(httpSchema))
      throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
    String responseStr = null;
    try {
      Map<String, String> headers = new HashMap<String, String>();
      if (Is.truthy(accept)) {
        headers.put("Accept", accept);
      } else {
        headers.put("Accept", "*/*");
      }
      if (Is.truthy(contentType)) {
        headers.put("Content-Type", contentType);
      } else {
        headers.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
      }
      Request request = new Request(Method.POST_FORM, httpSchema + config.host, path.get(httpSchema), config.appKey, config.appSecret, Constants.DEFAULT_TIMEOUT);
      request.setHeaders(headers);
      request.setQuerys(querys);
      request.setBodys(paramMap);
      Response response = Client.execute(request);
      responseStr = getResponseResult(response);
    } catch (Exception e) {
      logger.error("the Artemis PostForm Request is failed[doPostFormArtemis]", e);
    }
    return responseStr;
  }

  public static HttpResponse doPostFormImgArtemis(ArtemisConfig config, Map<String, String> path, Map<String, String> paramMap, Map<String, String> querys, String accept, String contentType, Map<String, String> header) {
    String httpSchema = (String) path.keySet().toArray()[0];
    if (Is.not().truthy(httpSchema))
      throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
    HttpResponse response = null;
    try {
      Map<String, String> headers = new HashMap<String, String>();
      if (Is.truthy(accept)) {
        headers.put("Accept", accept);
      } else {
        headers.put("Accept", "*/*");
      }
      if (Is.truthy(contentType)) {
        headers.put("Content-Type", contentType);
      } else {
        headers.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
      }
      if (header != null) {
        headers.putAll(header);
      }
      Request request = new Request(Method.POST_FORM_RESPONSE, httpSchema + config.host, path.get(httpSchema), config.appKey, config.appSecret, Constants.DEFAULT_TIMEOUT);
      request.setHeaders(headers);
      request.setQuerys(querys);
      request.setBodys(paramMap);
      Response response1 = Client.execute(request);
      response = response1.getResponse();
    } catch (Exception e) {
      logger.error("the Artemis PostForm Request is failed[doPostFormImgArtemis]", e);
    }
    return response;
  }

  public static String doPostStringArtemis(ArtemisConfig config, Map<String, String> path, String body, Map<String, String> querys, String accept, String contentType, Map<String, String> header) {
    String httpSchema = (String) path.keySet().toArray()[0];
    if (Is.not().truthy(httpSchema))
      throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
    String responseStr = null;
    try {
      Map<String, String> headers = new HashMap<String, String>();
      if (Is.truthy(accept)) {
        headers.put("Accept", accept);
      } else {
        headers.put("Accept", "*/*");
      }
      if (Is.truthy(contentType)) {
        headers.put("Content-Type", contentType);
      } else {
        headers.put("Content-Type", "application/text;charset=UTF-8");
      }
      if (header != null) {
        headers.putAll(header);
      }
      Request request = new Request(Method.POST_STRING, httpSchema + config.host, path.get(httpSchema), config.appKey, config.appSecret, Constants.DEFAULT_TIMEOUT);
      request.setHeaders(headers);
      request.setQuerys(querys);
      request.setStringBody(body);
      Response response = Client.execute(request);
      responseStr = getResponseResult(response);
    } catch (Exception e) {
      logger.error("the Artemis PostString Request is failed[doPostStringArtemis]", e);
    }
    return responseStr;
  }

  public static String doPostStringArtemis(ArtemisConfig config, Map<String, String> path, String body, Map<String, String> querys, String accept, String contentType) {
    String httpSchema = (String) path.keySet().toArray()[0];
    if (Is.not().truthy(httpSchema))
      throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
    String responseStr = null;
    try {
      Map<String, String> headers = new HashMap<String, String>();
      if (Is.truthy(accept)) {
        headers.put("Accept", accept);
      } else {
        headers.put("Accept", "*/*");
      }
      if (Is.truthy(contentType)) {
        headers.put("Content-Type", contentType);
      } else {
        headers.put("Content-Type", "application/text;charset=UTF-8");
      }
      Request request = new Request(Method.POST_STRING, httpSchema + config.host, path.get(httpSchema), config.appKey, config.appSecret, Constants.DEFAULT_TIMEOUT);
      request.setHeaders(headers);
      request.setQuerys(querys);
      request.setStringBody(body);
      Response response = Client.execute(request);
      responseStr = getResponseResult(response);
    } catch (Exception e) {
      logger.error("the Artemis PostString Request is failed[doPostStringArtemis]", e);
    }
    return responseStr;
  }

  public static HttpResponse doPostStringImgArtemis(ArtemisConfig config, Map<String, String> path, String body, Map<String, String> querys, String accept, String contentType, Map<String, String> header) {
    String httpSchema = (String) path.keySet().toArray()[0];
    if (Is.not().truthy(httpSchema))
      throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
    HttpResponse responseStr = null;
    try {
      Map<String, String> headers = new HashMap<String, String>();
      if (Is.truthy(accept)) {
        headers.put("Accept", accept);
      } else {
        headers.put("Accept", "*/*");
      }
      if (Is.truthy(contentType)) {
        headers.put("Content-Type", contentType);
      } else {
        headers.put("Content-Type", "application/text;charset=UTF-8");
      }
      if (header != null) {
        headers.putAll(header);
      }
      Request request = new Request(Method.POST_STRING_RESPONSE, httpSchema + config.host, path.get(httpSchema), config.appKey, config.appSecret, Constants.DEFAULT_TIMEOUT);
      request.setHeaders(headers);
      request.setQuerys(querys);
      request.setStringBody(body);
      Response response = Client.execute(request);
      responseStr = response.getResponse();
    } catch (Exception e) {
      logger.error("the Artemis PostString Request is failed[doPostStringArtemis]", e);
    }
    return responseStr;
  }

  public static String doPostBytesArtemis(ArtemisConfig config, Map<String, String> path, byte[] bytesBody, Map<String, String> querys, String accept, String contentType, Map<String, String> header) {
    String httpSchema = (String) path.keySet().toArray()[0];
    if (Is.not().truthy(httpSchema)) {
      throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
    }
    String responseStr = null;
    try {
      Map<String, String> headers = new HashMap<String, String>();
      if (Is.truthy(accept)) {
        headers.put("Accept", accept);
      } else {
        headers.put("Accept", "*/*");
      }
      if (bytesBody != null) {
        headers.put("Content-MD5", MessageDigestUtil.base64AndMD5(bytesBody));
      }
      if (Is.truthy(contentType)) {
        headers.put("Content-Type", contentType);
      } else {
        headers.put("Content-Type", "application/text;charset=UTF-8");
      }
      if (header != null) {
        headers.putAll(header);
      }
      Request request = new Request(Method.POST_BYTES, httpSchema + config.host, path.get(httpSchema), config.appKey, config.appSecret, Constants.DEFAULT_TIMEOUT);
      request.setHeaders(headers);
      request.setQuerys(querys);
      request.setBytesBody(bytesBody);
      Response response = Client.execute(request);
      responseStr = getResponseResult(response);
    } catch (Exception e) {
      logger.error("the Artemis PostBytes Request is failed[doPostBytesArtemis]", e);
    }
    return responseStr;
  }

  public static String doPostBytesArtemis(ArtemisConfig config, Map<String, String> path, byte[] bytesBody, Map<String, String> querys, String accept, String contentType) {
    String httpSchema = (String) path.keySet().toArray()[0];
    if (Is.not().truthy(httpSchema)) {
      throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
    }
    String responseStr = null;
    try {
      Map<String, String> headers = new HashMap<String, String>();
      if (Is.truthy(accept)) {
        headers.put("Accept", accept);
      } else {
        headers.put("Accept", "*/*");
      }
      if (bytesBody != null) {
        headers.put("Content-MD5", MessageDigestUtil.base64AndMD5(bytesBody));
      }
      if (Is.truthy(contentType)) {
        headers.put("Content-Type", contentType);
      } else {
        headers.put("Content-Type", "application/text;charset=UTF-8");
      }
      Request request = new Request(Method.POST_BYTES, httpSchema + config.host, path.get(httpSchema), config.appKey, config.appSecret, Constants.DEFAULT_TIMEOUT);
      request.setHeaders(headers);
      request.setQuerys(querys);
      request.setBytesBody(bytesBody);
      Response response = Client.execute(request);
      responseStr = getResponseResult(response);
    } catch (Exception e) {
      logger.error("the Artemis PostBytes Request is failed[doPostBytesArtemis]", e);
    }
    return responseStr;
  }

  public static String doPutStringArtemis(ArtemisConfig config, Map<String, String> path, String body, String accept, String contentType) {
    String httpSchema = (String) path.keySet().toArray()[0];
    if (Is.not().truthy(httpSchema)) {
      throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
    }
    String responseStr = null;
    try {
      Map<String, String> headers = new HashMap<String, String>();
      if (Is.truthy(accept)) {
        headers.put("Accept", accept);
      } else {
        headers.put("Accept", "*/*");
      }
      if (Is.truthy(body)) {
        headers.put("Content-MD5", MessageDigestUtil.base64AndMD5(body));
      }
      if (Is.truthy(contentType)) {
        headers.put("Content-Type", contentType);
      } else {
        headers.put("Content-Type", "application/text;charset=UTF-8");
      }
      Request request = new Request(Method.PUT_STRING, httpSchema + config.host, path.get(httpSchema), config.appKey, config.appSecret, Constants.DEFAULT_TIMEOUT);
      request.setHeaders(headers);
      request.setStringBody(body);
      Response response = Client.execute(request);
      responseStr = getResponseResult(response);
    } catch (Exception e) {
      logger.error("the Artemis PutString Request is failed[doPutStringArtemis]", e);
    }
    return responseStr;
  }

  public static String doPutBytesArtemis(ArtemisConfig config, Map<String, String> path, byte[] bytesBody, String accept, String contentType) {
    String httpSchema = (String) path.keySet().toArray()[0];
    if (Is.not().truthy(httpSchema)) {
      throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
    }
    String responseStr = null;
    try {
      Map<String, String> headers = new HashMap<String, String>();
      if (Is.truthy(accept)) {
        headers.put("Accept", accept);
      } else {
        headers.put("Accept", "*/*");
      }
      if (bytesBody != null) {
        headers.put("Content-MD5", MessageDigestUtil.base64AndMD5(bytesBody));
      }
      if (Is.truthy(contentType)) {
        headers.put("Content-Type", contentType);
      } else {
        headers.put("Content-Type", "application/text;charset=UTF-8");
      }
      Request request = new Request(Method.PUT_BYTES, httpSchema + config.host, path.get(httpSchema), config.appKey, config.appSecret, Constants.DEFAULT_TIMEOUT);
      request.setHeaders(headers);
      request.setBytesBody(bytesBody);
      Response response = Client.execute(request);
      responseStr = getResponseResult(response);
    } catch (Exception e) {
      logger.error("the Artemis PutBytes Request is failed[doPutBytesArtemis]", e);
    }
    return responseStr;
  }

  public static String doDeleteArtemis(ArtemisConfig config, Map<String, String> path, Map<String, String> querys, String accept, String contentType) {
    String httpSchema = (String) path.keySet().toArray()[0];
    if (Is.not().truthy(httpSchema)) {
      throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
    }
    String responseStr = null;
    try {
      Map<String, String> headers = new HashMap<String, String>();
      if (Is.truthy(accept)) {
        headers.put("Accept", accept);
      } else {
        headers.put("Accept", "*/*");
      }
      if (Is.truthy(contentType)) {
        headers.put("Content-Type", contentType);
      }
      Request request = new Request(Method.DELETE, httpSchema + config.host, path.get(httpSchema), config.appKey, config.appSecret, Constants.DEFAULT_TIMEOUT);
      request.setHeaders(headers);
      request.setQuerys(querys);
      Response response = Client.execute(request);
      responseStr = getResponseResult(response);
    } catch (Exception e) {
      logger.error("the Artemis DELETE Request is failed[doDeleteArtemis]", e);
    }
    return responseStr;
  }

  private static String getResponseResult(Response response) {
    String responseStr = null;
    int statusCode = response.getStatusCode();
    if (String.valueOf(statusCode).startsWith("2") || String.valueOf(statusCode).startsWith("3")) {
      responseStr = response.getBody();
      logger.info("the Artemis Request is Success,statusCode:" + statusCode + " SuccessMsg:" + response.getBody());
    } else {
      String msg = response.getErrorMessage();
      responseStr = response.getBody();
      logger.error("the Artemis Request is Failed,statusCode:" + statusCode + " errorMsg:" + msg);
    }
    return responseStr;
  }
}
